package com.github.florent37.shapeofview.shapes;


import ohos.agp.components.AttrSet;
import ohos.agp.render.Path;
import ohos.app.Context;

import com.github.florent37.shapeofview.ShapeOfView;
import com.github.florent37.shapeofview.manager.ClipPathManager;
import com.github.florent37.shapeofview.manager.ResourceTable;

/**
 * ArcView
 *
 * @since 2021-07-22
 */
public class ArcView extends ShapeOfView {

    public static final int POSITION_BOTTOM = 1;
    public static final int POSITION_TOP = 2;
    public static final int POSITION_LEFT = 3;
    public static final int POSITION_RIGHT = 4;

    public static final int CROP_INSIDE = 1;
    public static final int CROP_OUTSIDE = 2;

    private int arcPosition = POSITION_BOTTOM;


    private float arcHeightPx = 0f;

    /**
     * ArcView
     *
     * @param context context
     */
    public ArcView(Context context) {
        super(context);
        init(context, null);
    }

    /**
     * ArcView
     *
     * @param context context
     * @param attrs attrs
     */
    public ArcView(Context context, AttrSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    /**
     * ArcView
     *
     * @param context context
     * @param attrs attrs
     * @param defStyleAttr defStyleAttr
     */
    public ArcView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttrSet attrs) {
        if (attrs != null) {
            try {
                String[] strings = getResourceManager().getElement(ResourceTable.Strarray_shape_arc_position).getStringArray();
                arcHeightPx = attrs.getAttr("shape_arc_height").get().getIntegerValue();
                arcPosition = Integer.parseInt(strings[arcPosition - 1]);
            } catch (Exception e) {
                System.out.println("ee===" + e.getMessage());
            }

        }
        super.setClipPathCreator(new ClipPathManager.ClipPathCreator() {
            @Override
            public Path createClipPath(int width, int height) {
                final Path path = new Path();

                final boolean isCropInside = getCropDirection() == CROP_INSIDE;

                final float arcHeightAbs = Math.abs(arcHeightPx);

                switch (arcPosition) {
                    case POSITION_BOTTOM: {
                        if (isCropInside) {
                            path.moveTo(0, 0);
                            path.lineTo(0, height);
                            path.quadTo((float) width / 2, (float) height - 2 * arcHeightAbs, width, height);
                            path.lineTo(width, 0);
                            path.close();
                        } else {
                            path.moveTo(0, 0);
                            path.lineTo(0, height - arcHeightAbs);
                            path.quadTo((float) width / 2, height + arcHeightAbs, width, height - arcHeightAbs);
                            path.lineTo(width, 0);
                            path.close();
                        }
                        break;
                    }
                    case POSITION_TOP:
                        if (isCropInside) {
                            path.moveTo(0, height);
                            path.lineTo(0, 0);
                            path.quadTo((float) width / 2, 2 * arcHeightAbs, width, 0);
                            path.lineTo(width, height);
                            path.close();
                        } else {
                            path.moveTo(0, arcHeightAbs);
                            path.quadTo((float) width / 2, -arcHeightAbs, width, arcHeightAbs);
                            path.lineTo(width, height);
                            path.lineTo(0, height);
                            path.close();
                        }
                        break;
                    case POSITION_LEFT:
                        if (isCropInside) {
                            path.moveTo(width, 0);
                            path.lineTo(0, 0);
                            path.quadTo(arcHeightAbs * 2, (float) height / 2, 0, height);
                            path.lineTo(width, height);
                            path.close();
                        } else {
                            path.moveTo(width, 0);
                            path.lineTo(arcHeightAbs, 0);
                            path.quadTo(-arcHeightAbs, (float) height / 2, arcHeightAbs, height);
                            path.lineTo(width, height);
                            path.close();
                        }
                        break;
                    case POSITION_RIGHT:
                        if (isCropInside) {
                            path.moveTo(0, 0);
                            path.lineTo(width, 0);
                            path.quadTo((float) width - arcHeightAbs * 2, (float) height / 2, width, height);
                            path.lineTo(0, height);
                            path.close();
                        } else {
                            path.moveTo(0, 0);
                            path.lineTo(width - arcHeightAbs, 0);
                            path.quadTo(width + arcHeightAbs, (float) height / 2, width - arcHeightAbs, height);
                            path.lineTo(0, height);
                            path.close();
                        }
                        break;

                }
                return path;
            }

            @Override
            public boolean requiresBitmap() {
                return false;
            }
        });
    }

    /**
     * getArcPosition
     *
     * @return 1
     */
    public int getArcPosition() {
        return arcPosition;
    }

    /**
     * setArcPosition
     *
     * @param arcPosition arcPosition
     */
    public void setArcPosition(int arcPosition) {
        this.arcPosition = arcPosition;
        requiresShapeUpdate();
    }

    /**
     * getCropDirection
     *
     * @return 1
     */
    public int getCropDirection() {
        return arcHeightPx > 0 ? CROP_OUTSIDE : CROP_INSIDE;
    }

    /**
     * getArcHeight
     *
     * @return float
     */
    public float getArcHeight() {
        return arcHeightPx;
    }

    /**
     * setArcHeight
     *
     * @param arcHeight arcHeight
     */
    public void setArcHeight(float arcHeight) {
        this.arcHeightPx = arcHeight;
        requiresShapeUpdate();
    }

//    public float getArcHeightDp() {
//        return pxToDp(arcHeightPx);
//    }
//
//    public void setArcHeightDp(float arcHeight) {
//        this.setArcHeight(dpToPx(arcHeight));
//    }

}
